package BLC

import (
	"bytes"
	"crypto/sha256"
	"encoding/gob"
	"log"
	"time"
)

type Block struct {
	//1.区块高度
	Height int64
	//2.上一个区块的hash
	PrevBlockHash []byte
	//3.交易数据
	Txs []*Transaction
	//4.时间戳
	Timestamp int64
	//5.Hash
	Hash []byte
	//6 Nonce
	Nonce int64
}

//需要将Txs转成[]byte
func (block *Block) HashTransaction() []byte {

	var txHashes [][]byte
	var txHash [32]byte

	for _, tx := range block.Txs {
		txHashes = append(txHashes, tx.TxHash)
	}
	txHash = sha256.Sum256(bytes.Join(txHashes, []byte{}))

	return txHash[:]
}

// 区块链序列化
func (block *Block) SeriaLize() []byte {

	var result bytes.Buffer
	encoder := gob.NewEncoder(&result)

	err := encoder.Encode(block)
	if err != nil {
		log.Panic(err)
	}
	return result.Bytes()
}

func DeserializeBlock(blockBytes []byte) *Block {

	var block Block

	decoder := gob.NewDecoder(bytes.NewReader(blockBytes))
	err := decoder.Decode(&block)
	if err != nil {
		log.Panic(err)
	}

	return &block
}

//1. 创建新的区块
func NewBlock(txs []*Transaction, height int64, PrevBlockHash []byte) *Block {

	// 1 创建区块
	block := &Block{height, PrevBlockHash, txs,
		time.Now().Unix(), nil, 0}

	// 调用工作量证明的方法返回有效的hash和nonce
	pow := NewProofOfWork(block)

	hash, nonce := pow.Run()

	block.Hash = hash[:]
	block.Nonce = nonce

	return block
}

//2. 单独写一个创世区块的方法
func CreateGenesisBlock(txs []*Transaction) *Block {

	return NewBlock(txs, 1, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
}
